home *** CD-ROM | disk | FTP | other *** search
/ CD Fun House 1 / CD Fun House (Wayzata Technology).iso / •Word Games• / WordFind ••• / Source / placeword next >
Text File  |  1987-11-14  |  7KB  |  329 lines

  1. UNIT placepuzzle;
  2. INTERFACE
  3.     USES
  4.         stringf;
  5.     CONST
  6.         MAXX = 30;
  7.         MAXY = 30;
  8.     TYPE
  9.         cell = RECORD
  10.                 ch : char;
  11.                 boldf : boolean;
  12.             END;
  13.         cmat = ARRAY[1..MAXX, 1..MAXY] OF cell;
  14.     VAR
  15.         XMAX : integer;
  16.         YMAX : integer;
  17.         puzzle : cmat;
  18.     FUNCTION randnum (x : integer) : integer;
  19.     FUNCTION rightlen (word : STRING) : boolean;
  20.     FUNCTION placerandom (word : STRING) : boolean;
  21.     FUNCTION placeanyplace (word : STRING) : boolean;
  22. IMPLEMENTATION
  23.     TYPE
  24.         location = RECORD
  25.                 x : integer;
  26.                 y : integer;
  27.             END;
  28.  
  29.         crose = (north, south, east, west, northeast, northwest, southeast, southwest);
  30.         compass = SET OF crose;
  31.         randrec = RECORD
  32.                 xp, yp : integer;
  33.                 dir : crose;
  34.                 incx, incy : integer; {used to check fit}
  35.             END;
  36.     VAR
  37.         rrec : randrec;
  38.     FUNCTION randnum;
  39. { returns a random number between x and 1 }
  40.         VAR
  41.             y, z : real;
  42.     BEGIN
  43.         y := abs(Random);
  44.         z := (y / 32768.0);
  45.         randnum := integer(trunc(x * z)) + 1;
  46.     END;
  47.     PROCEDURE getinc (VAR x, y : integer;
  48.                                     d : crose);
  49.     BEGIN
  50.         CASE d OF
  51.             north, south : 
  52.                 BEGIN
  53.                     y := 1;
  54.                     x := 0;
  55.                 END;
  56.             east, west : 
  57.                 BEGIN
  58.                     y := 0;
  59.                     x := 1;
  60.                 END;
  61.             northeast, southwest : 
  62.                 BEGIN
  63.                     x := -1;
  64.                     y := 1;
  65.                 END;
  66.             northwest, southeast : 
  67.                 BEGIN
  68.                     x := 1;
  69.                     y := 1;
  70.                 END;
  71.         END;
  72.     END;
  73.     PROCEDURE getrand (VAR r : randrec);
  74.         VAR
  75.             xi, yi : integer;
  76.     BEGIN
  77.         r.xp := randnum(XMAX);
  78.         r.yp := randnum(YMAX);
  79.         CASE randnum(8) OF
  80.             1 : 
  81.                 r.dir := north;
  82.             2 : 
  83.                 r.dir := south;
  84.             3 : 
  85.                 r.dir := east;
  86.             4 : 
  87.                 r.dir := west;
  88.             5 : 
  89.                 r.dir := northeast;
  90.             6 : 
  91.                 r.dir := northwest;
  92.             7 : 
  93.                 r.dir := southeast;
  94.             8 : 
  95.                 r.dir := southwest;
  96.         END;
  97.         getinc(xi, yi, r.dir);
  98.         r.incx := xi;
  99.         r.incy := yi;
  100.     END;
  101.     FUNCTION placerandom;
  102.  
  103.         VAR
  104.             backwords : SET OF crose;
  105.             i, j, k, x, y : integer;
  106.             len : integer;
  107.             ok : boolean;
  108.     BEGIN
  109.         len := length(word);
  110.         backwords := [east, north, northeast, southeast];
  111.         ok := true;
  112.         getrand(rrec);
  113.         IF rrec.dir IN backwords THEN
  114.             wreverse(word);
  115.         CASE rrec.dir OF
  116.             north, south : 
  117.                 BEGIN
  118.                     IF YMAX - rrec.yp + 1 < len THEN
  119.                         ok := false;
  120.                 END;
  121.             east, west : 
  122.                 BEGIN
  123.                     IF XMAX - rrec.xp + 1 < len THEN
  124.                         ok := false;
  125.                 END;
  126.             northwest, southeast : 
  127.                 BEGIN
  128.                     IF (XMAX - rrec.xp + 1 < len) OR (YMAX - rrec.yp + 1 < len) THEN
  129.                         ok := false;
  130.                 END;
  131.             northeast, southwest : 
  132.                 BEGIN
  133.                     IF (rrec.xp < len) OR (YMAX - rrec.yp + 1 < len) THEN
  134.                         ok := false;
  135.                 END;
  136.         END;
  137.         IF ok = true THEN
  138. {it has now passed the first test}
  139.             BEGIN
  140.                 x := rrec.xp; (* set up the pointers *)
  141.                 y := rrec.yp;
  142.                 i := 1;
  143.                 WHILE ((puzzle[x, y].ch = ' ') OR (puzzle[x, y].ch = word[i])) AND (i < len) DO
  144.                     BEGIN
  145.                         x := x + rrec.incx;
  146.                         y := y + rrec.incy;
  147.                         i := i + 1;
  148.                     END;
  149.                 IF (i = len) AND ((puzzle[x, y].ch = word[i]) OR (puzzle[x, y].ch = ' ')) THEN
  150.             (* we made it!!! The word fits into the puzzle;  put it in!!!*)
  151.                     BEGIN
  152.                         ok := true;
  153.                         x := rrec.xp;
  154.                         y := rrec.yp;
  155.                         FOR i := 1 TO len DO
  156.                             BEGIN
  157.                                 puzzle[x, y].ch := word[i];
  158.                                 puzzle[x, y].boldf := true;
  159.                                 x := x + rrec.incx;
  160.                                 y := y + rrec.incy;
  161.                             END;
  162.                     END
  163.                 ELSE
  164.                     ok := false;
  165.             END;
  166.         placerandom := ok;
  167.     END;
  168.  
  169.     FUNCTION rightlen; (* will the word fit on the screen?*)
  170.     BEGIN
  171.         IF (length(word) > XMAX) AND (length(word) > YMAX) THEN
  172.             rightlen := false
  173.         ELSE
  174.             rightlen := true;
  175.     END;
  176. {}
  177.  
  178.  
  179. {This routine will do anything to get a word into the puzzle}
  180.  
  181.     FUNCTION placeanyplace; (* get it in there anyway you have to*)
  182.         CONST
  183.             NUMDIR = 8;
  184.         LABEL
  185.             100;
  186.         VAR
  187.             pword : STRING;
  188.             ok : boolean; (*this is used to get us out of the loop*)
  189.             xi, yi, lcount, len, x, y : integer;
  190.             incx, incy : integer;
  191.             backwords : SET OF crose;
  192.             dirset, dirarray : ARRAY[1..NUMDIR] OF integer;
  193.             dirptr : integer;
  194.             whichway : crose;
  195.             dircount : integer;
  196.         PROCEDURE setrandlist;
  197.             VAR
  198.                 i, j : integer;
  199.                 rdir : integer;
  200.                 d : crose;
  201.                 num : integer;
  202.         BEGIN
  203.             FOR i := 1 TO NUMDIR DO { create array of possible values }
  204.                 dirset[i] := i;
  205.             FOR i := 1 TO NUMDIR DO { pick one at random and assign it to a slot in dirarray}
  206.                 BEGIN
  207.                     IF i < NUMDIR THEN
  208.                         rdir := randnum(NUMDIR - i + 1)
  209.                     ELSE
  210.                         rdir := 1;
  211.                     dirarray[i] := dirset[rdir];
  212.                     IF i <> NUMDIR THEN
  213.                         FOR j := rdir TO NUMDIR - i DO
  214.                             dirset[j] := dirset[j + 1];
  215.                 END;
  216.             dirptr := 1;
  217.         END;
  218.         FUNCTION getdir : crose;
  219.             VAR
  220.                 dircnt, d : crose;
  221.                 i : integer;
  222.         BEGIN
  223.             IF dirarray[dirptr] = 1 THEN
  224.                 getdir := north
  225.             ELSE
  226.                 BEGIN
  227.                     d := north;
  228.                     FOR i := 1 TO dirarray[dirptr] - 1 DO
  229.                         d := succ(d);  (* bump up direction*)
  230.                     getdir := d;
  231.                 END;
  232.             IF dirptr < NUMDIR THEN
  233.                 dirptr := dirptr + 1;
  234.         END;
  235.  
  236.     BEGIN
  237.         setrandlist;
  238.         backwords := [east, north, northeast, southeast];
  239.         dircount := 1;
  240.         whichway := getdir;
  241.         len := length(word);
  242.         xi := 1;
  243.         yi := 1;
  244.         REPEAT
  245.             ok := true;
  246.             pword := word;
  247.             IF whichway IN backwords THEN
  248.                 wreverse(pword);
  249.             getinc(incx, incy, whichway);
  250. (**)
  251. (*Will this fit in the spot we have chosen?*)
  252. (**)
  253.             CASE whichway OF
  254.                 north, south : 
  255.                     BEGIN
  256.                         IF YMAX - yi + 1 < len THEN
  257.                             ok := false;
  258.                     END;
  259.                 east, west : 
  260.                     BEGIN
  261.                         IF XMAX - xi + 1 < len THEN
  262.                             ok := false;
  263.                     END;
  264.                 northwest, southeast : 
  265.                     BEGIN
  266.                         IF (XMAX - xi + 1 < len) OR (YMAX - yi + 1 < len) THEN
  267.                             ok := false;
  268.                     END;
  269.                 northeast, southwest : 
  270.                     BEGIN
  271.                         IF (xi < len) OR (YMAX - yi + 1 < len) THEN
  272.                             ok := false;
  273.                     END;
  274.             END; {end case}
  275.             IF ok = true THEN
  276. {it has now passed the first test}
  277. {there is room for it}
  278.                 BEGIN
  279.                     x := xi; (* set up the pointers *)
  280.                     y := yi;
  281.                     lcount := 1;
  282.                     WHILE ((puzzle[x, y].ch = ' ') OR (puzzle[x, y].ch = word[lcount])) AND (lcount < len) DO
  283.                         BEGIN
  284.                             x := x + incx;
  285.                             y := y + incy;
  286.                             lcount := lcount + 1;
  287.                         END;
  288.                     IF ((lcount = len) AND (puzzle[x, y].ch = word[lcount])) OR ((lcount = len) AND (puzzle[x, y].ch = ' ')) THEN
  289.             (* we made it!!! The word fits into the puzzle;  put it in!!!*)
  290.                         BEGIN
  291.                             ok := true;
  292.                             x := xi;
  293.                             y := yi;
  294.                             FOR lcount := 1 TO len DO
  295.                                 BEGIN
  296.                                     puzzle[x, y].ch := word[lcount];
  297.                                     puzzle[x, y].boldf := true;
  298.                                     x := x + incx;
  299.                                     y := y + incy;
  300.                                 END; {end for}
  301.                         END {end if}
  302.  { didn't fit in the space}
  303.                     ELSE
  304.                         ok := false;
  305.                 END
  306.             ELSE
  307.                 ok := false;
  308.  
  309.             IF (ok = false) THEN
  310.                 IF xi = XMAX THEN
  311.                     IF yi <> YMAX THEN {are we at the end of a line}
  312.                         BEGIN
  313.                             xi := 1; { move to the beginning}
  314.                             yi := yi + 1; {and bump up y}
  315.                         END
  316.                     ELSE IF dircount <> NUMDIR THEN
  317.                         BEGIN
  318.                             whichway := getdir;
  319.                             dircount := dircount + 1;
  320.                         END
  321.                     ELSE
  322.                         GOTO 100 {get out of here we have failed}
  323.                 ELSE IF (ok = false) AND (xi < XMAX) THEN
  324.                     xi := xi + 1;
  325.         UNTIL (ok = true);
  326. 100 :
  327.         placeanyplace := ok;
  328.     END;
  329. END.